package com.liuyjy.base.common.util;

import com.google.common.collect.Lists;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author liuyjy
 * @Date 2022/3/2 14:02
 * @Description: 树型结构拼接
 **/
public class TreeUtil {


    /**
     * 获取树形结构
     *
     * @param list 对象
     * @return treeList 树形结果集
     */
    public static <T> List<Map<String, Object>> getTree(List<T> list) {
        return getTree(list, "id");
    }

    /**
     * 获取树形结构
     *
     * @param list            对象
     * @param primaryKeyField 主键字段
     * @return treeList 树形结果集
     */
    public static <T> List<Map<String, Object>> getTree(List<T> list, String primaryKeyField) {
        return getTree(list, primaryKeyField, 0L);
    }

    /**
     * 获取树形结构
     *
     * @param list            对象
     * @param rootNodeValue   根节点值
     * @param primaryKeyField 主键字段
     * @return treeList 树形结果集
     */
    public static <T> List<Map<String, Object>> getTree(List<T> list, String primaryKeyField, Object rootNodeValue) {
        return getTree(list, rootNodeValue, primaryKeyField, "parentId");
    }

    /**
     * 获取树形结构
     *
     * @param list            对象
     * @param parentField     关系字段
     * @param rootNodeValue   根节点值
     * @param primaryKeyField 主键字段
     * @return treeList 树形结果集
     */
    public static <T> List<Map<String, Object>> getTree(List<T> list, Object rootNodeValue, String primaryKeyField, String parentField) {
        return getTree(list, parentField, rootNodeValue, null, primaryKeyField);
    }

    /**
     * 获取树形结构
     *
     * @param list            对象
     * @param sortField       排序字段
     * @param primaryKeyField 主键字段
     * @return treeList 树形结果集
     */
    public static <T> List<Map<String, Object>> getTree(List<T> list, String sortField, String primaryKeyField) {
        return getTree(list, "parentId", sortField, primaryKeyField);
    }

    /**
     * 获取树形结构
     *
     * @param list            对象
     * @param sortField       排序字段
     * @param rootNodeValue   根节点值
     * @param primaryKeyField 主键字段
     * @return treeList 树形结果集
     */
    public static <T> List<Map<String, Object>> getTreeNew(List<T> list, String sortField, Object rootNodeValue, String primaryKeyField) {
        return getTree(list, "parentId", rootNodeValue, sortField, primaryKeyField);
    }


    /**
     * 获取树形结构
     *
     * @param list            对象
     * @param parentField     关系字段
     * @param rootNodeValue   根节点值
     * @param sortField       排序字段
     * @param primaryKeyField 主键字段
     * @return treeList 树形结果集
     */
    public static <T> List<Map<String, Object>> getTree(List<T> list, String parentField, Object rootNodeValue, String sortField, String primaryKeyField) {
        if (EmptyUtil.isEmpty(list)) {
            return Lists.newArrayList();
        }
        //转化为Map集合
        List<Map<String, Object>> mapList = ObjConvertUtil.objToMap(list);
        return getTreeMap(mapList, parentField, rootNodeValue, sortField, primaryKeyField);
    }

    /**
     * 获取树形结构
     *
     * @param list            对象
     * @param parentField     关系字段
     * @param sortField       排序字段
     * @param primaryKeyField 主键字段
     * @return treeList 树形结果集
     */
    public static <T> List<Map<String, Object>> getTree(List<T> list, String parentField, String sortField, String primaryKeyField) {
        if (EmptyUtil.isEmpty(list)) {
            return Lists.newArrayList();
        }
        //转化为Map集合
        List<Map<String, Object>> mapList = ObjConvertUtil.objToMap(list);
        return getTreeMap(mapList, parentField, 0L, sortField, primaryKeyField);
    }

    /**
     * 获取树形结构
     *
     * @param mapList         对象
     * @param parentField     关系字段
     * @param rootNodeValue   根节点值
     * @param sortField       排序字段
     * @param primaryKeyField 主键字段
     * @return
     */
    public static List<Map<String, Object>> getTreeMap(List<Map<String, Object>> mapList, String parentField,
                                                       Object rootNodeValue, String sortField, String primaryKeyField) {
        if (EmptyUtil.isEmpty(mapList)) {
            return Lists.newArrayList();
        }
        //filter过滤出所有的一级节点
        return mapList.stream().filter(m ->
                        Objects.equals(m.get(parentField), rootNodeValue))
                .peek(m -> m.put("children", sortMap(getChildren(m, mapList, parentField, primaryKeyField), sortField))).collect(Collectors.toList());
    }


    /**
     * 根据父级节点获取所有的子集节点
     *
     * @param parentNode      单条数据
     * @param allList         对象
     * @param parentField     关系字段
     * @param primaryKeyField 主键字段
     * @return
     */
    private static List<Map<String, Object>> getChildren(Map<String, Object> parentNode, List<Map<String, Object>> allList, String parentField, String primaryKeyField) {
        return allList.stream()
                .filter(curNode -> EmptyUtil.isNotEmpty(curNode.get(parentField)) && Objects.equals(curNode.get(parentField), parentNode.get(primaryKeyField)))
                .peek(m -> m.put("children", getChildren(m, allList, parentField, primaryKeyField))).collect(Collectors.toList());
    }


    /**
     * 树性结构排序
     *
     * @param list      树
     * @param sortField 排序字段
     * @return List
     */
    public static List<Map<String, Object>> sortMap(List<Map<String, Object>> list, String sortField) {
        if (EmptyUtil.isEmpty(list)) {
            return Lists.newArrayList();
        }
        if (EmptyUtil.isEmpty(sortField)) {
            return list;
        }
        //关键之处，一行代码搞定
        list.sort(Comparator.comparing(m -> String.valueOf(m.get(sortField))));
        return list;
    }


}
